package com.scs.application.modules.finance.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.flow.FlowContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.core.utils.UtilNum;
import com.scs.application.modules.finance.entity.AccountCheck;
import com.scs.application.modules.finance.entity.Bill;
import com.scs.application.modules.finance.mapper.AccountCheckMapper;
import com.scs.application.modules.finance.service.AccountCheckService;
import com.scs.application.modules.finance.service.BillService;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.wm.entity.WorkOrder;
import com.scs.application.modules.wm.enums.WorkOrderType;
import com.scs.application.modules.wm.service.WorkOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
* @Description：扎账单服务类
*/
@Service
@Slf4j
public class AccountCheckServiceImpl extends BaseServiceImpl<AccountCheckMapper, AccountCheck> implements AccountCheckService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private WorkOrderService workOrderService;


    @Autowired
    private BillService billService;


    @Transactional(rollbackFor = Exception.class)
    public RestResult checkInit(Map<String, String> reqData) {
        RestResult restResult =RestResult.ok();
        String msg="";
        Date dateNow=new Date();
        String endDate=reqData.get("endDate"),dateNowString= DateUtils.getDate(dateNow),loginUname=UserUtils.currentUser().getName();
        if(StringUtils.isBlank(endDate)) throw new BusinessException("缺少参数【endDate】");

        //1、更新未审核的扎账单日期
        int count =baseMapper.updateBusDateCurrent(dateNowString);
        if(count > 0) msg += ",更新扎账单数量:"+count;

        //2、需要创建扎账单的科室列表
        List<Map> depts=baseMapper.getAccountCheckAddDepts(endDate,StringUtils.join(WorkOrderType.BUSTYPE_ALL,","));
        List<AccountCheck> accountChecks=new ArrayList<AccountCheck>();
        AccountCheck accountCheck;
        if(depts!=null && depts.size()>0){
            msg += ",新增扎账单数量:"+depts.size();
            for(Map dept : depts){
                accountCheck = new AccountCheck();
                accountCheck.setBusDateCurrent(DateUtils.parse(dept.get("gmtModified")+""))
                        .setDeptId(dept.get("deptId")+"").setDeptName(dept.get("deptName")+"")
                        .setBusDate(dateNow).setBusUser(loginUname).setBusUserCode(UserUtils.currentUser().getWorkNo()).setFlowStatus("start");;
                accountChecks.add(accountCheck);
            }
        }
        if(accountChecks.size() > 0) super.saveOrUpdateBatch(accountChecks);

        if(accountChecks.size()+count > 0){
            //4、更新记账单关联关系
            count=baseMapper.updateBillAccountCheckId(endDate,StringUtils.join(WorkOrderType.BUSTYPE_ALL,","));
            if(count > 0)  msg += ",更新记账单单数量:"+count;

            //5、设置各种统计金额信息
            baseMapper.updateAllAmountSum(StringUtils.join(WorkOrderType.BUSTYPE_DIST,","),StringUtils.join(WorkOrderType.BUSTYPE_DEPTUSE,","),StringUtils.join(WorkOrderType.BUSTYPE_PATIENT,","));
        }else{
            msg += ",暂无科室可扎账数据";
        }
        restResult.setMsg(restResult.getMsg()+msg);
        return restResult;
    }

    /**
    * @Description：业务单号扫描扎账
    * @Author wyt
    * @Date 2020/9/2
    */
    @Transactional(rollbackFor = Exception.class)
    public void scanBusKey(String busKey) {
        WorkOrder workOrder = workOrderService.getOne(Wrappers.<WorkOrder>query().eq("ref_key",busKey).last("limit 1"));
        if(workOrder == null) throw new BusinessException("【"+busKey+"】业务单号未找到相关单据");
        if(!"end".equals(workOrder.getFlowStatus())) throw new BusinessException("【"+busKey+"】业务单号未审核，无法进行扎账操作");

        Bill bill = billService.getOne(Wrappers.<Bill>query().eq("ref_key", workOrder.getBusKey()).last("limit 1"));
        if(bill == null) throw new BusinessException("【"+busKey+"】业务单号未找到相关记账单据");
        if(!"end".equals(bill.getFlowStatus())) throw new BusinessException("【"+busKey+"】业务单号相关记账单据未审核，无法进行扎账操作");
        if(StringUtils.isBlank(bill.getAccountCheckId())) throw new BusinessException("【"+busKey+"】业务单号不在扎账范围内");
        if("end".equals(bill.getAccountCheckStatus())) throw new BusinessException("【"+busKey+"】业务单号已扎账，请勿重复操作");
        if(workOrder.getAmount() != Math.abs(bill.getAmount())) throw new BusinessException("【"+busKey+"】业务单号合计金额【"+workOrder.getAmount()+"】与对应账单合计金额【"+bill.getAmount()+"】不一致");

        //1、更新记账单扎账状态
        billService.update(Wrappers.<Bill>update().set("account_check_status","end").eq("id",bill.getId()));

        //2、更新扎账单对应类型数量和金额
        AccountCheck accountCheck=this.getById(bill.getAccountCheckId());
        String busTypeMatch="'"+workOrder.getBusType()+"'";

        if(WorkOrderType.BUSTYPE_DIST.stream().anyMatch(s -> Objects.equals(s,busTypeMatch ))){ //配送出库类型
            accountCheck.setAmountOutCheck(UtilNum.sum(accountCheck.getAmountOutCheck(),workOrder.getAmount()));
            accountCheck.setSumOutCheck(UtilNum.sum(accountCheck.getSumOutCheck(),1));
        }else if(WorkOrderType.BUSTYPE_DEPTUSE.stream().anyMatch(s -> Objects.equals(s, busTypeMatch))){//消耗出库类型
            accountCheck.setAmountUseCheck(UtilNum.sum(accountCheck.getAmountUseCheck(),workOrder.getAmount()) );
            accountCheck.setSumUseCheck(UtilNum.sum(accountCheck.getSumUseCheck(),1));
        }else if(WorkOrderType.BUSTYPE_PATIENT.stream().anyMatch(s -> Objects.equals(s, busTypeMatch))){ //病人计费类型
            accountCheck.setAmountPatientCheck(UtilNum.sum(accountCheck.getAmountPatientCheck(),workOrder.getAmount()));
            accountCheck.setSumPatientCheck(UtilNum.sum(accountCheck.getSumPatientCheck(),1));
        }else{
            throw new BusinessException("【"+busKey+"】业务单号类型非法");
        }
        this.updateById(accountCheck);


    }


    /**
    * @Description：流程处理前
    */
    protected void beforeHandleFlowChange(FlowContext flowContext, AccountCheck accountCheck) {
    }

    /**
    * @Description：流程处理后
    */
    @Transactional(rollbackFor = Exception.class)
    protected void afterHandleFlowChange(FlowContext flowContext, AccountCheck accountCheck) {
    }

    /**
     * @Description：批量审核
     */
    @Transactional(rollbackFor = Exception.class)
    public void auditBatch(JSONArray idArr) {
        int count=this.count(Wrappers.<AccountCheck>query().eq("flow_status","end"). in("id",idArr) );
        if(count >0) throw new BusinessException("有"+count+"条扎账单已被审核，请刷新页面后重新提交批量操作");
        this.update(Wrappers.<AccountCheck>update().set("flow_status","end").eq("flow_status","start"). in("id",idArr) );
    }

    /**
    * @Description：查询扎账单唯一部门列表
    */
    public List getDeptsUnique() {
        return jdbcTemplate.queryForList(" select distinct  dept_id,dept_name from finance_account_check  order by dept_name ");
    }

}
